package cn.cellcom.adapter.service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.scienjus.smartqq.client.SmartQQClient;
import com.scienjus.smartqq.model.Message;
import com.scienjus.smartqq.model.UserInfo;

import cn.cellcom.agent.biz.Org00Biz;
import cn.cellcom.agent.biz.TButtonBiz;
import cn.cellcom.agent.biz.TChannelBiz;
import cn.cellcom.agent.biz.TCrmBiz;
import cn.cellcom.agent.biz.TGroupBiz;
import cn.cellcom.agent.biz.TLwBiz;
import cn.cellcom.agent.biz.TQuestionBiz;
import cn.cellcom.agent.biz.TSessionBiz;
import cn.cellcom.agent.biz.TSettingBiz;
import cn.cellcom.agent.common.AgentConstant;
import cn.cellcom.agent.common.AgentConstant.WECHAT_STEP;
import cn.cellcom.agent.entity.TSettingEntity;
import cn.cellcom.agent.online.client.ClientManager;
import cn.cellcom.agent.online.client.QqClient;
import cn.cellcom.agent.online.iq.ProcessorResult;
import cn.cellcom.agent.online.iq.agent.LwDetailProcessor;
import cn.cellcom.agent.online.iq.visitor.ButtonProcessor;
import cn.cellcom.agent.online.iq.visitor.GetGroupListProcessor;
import cn.cellcom.agent.online.iq.visitor.LwProcessor;
import cn.cellcom.agent.online.iq.visitor.SatisfyProcessor;
import cn.cellcom.agent.online.iq.visitor.VisitorProcessors;
import cn.cellcom.agent.online.message.MessageConstant;
import cn.cellcom.agent.online.wrapper.SessionWrapper;
import cn.cellcom.agent.pojo.TChannel;
import cn.cellcom.agent.pojo.TCrm;
import cn.cellcom.agent.pojo.TGroup;
import cn.cellcom.agent.pojo.TOrg;
import cn.cellcom.agent.struts.form.VisitorForm;
import cn.cellcom.jar.biz.AbstractBiz;
import cn.cellcom.jar.util.CU;
import cn.cellcom.jar.util.MyException;

public class QqVisitorHandler {

	private static TSettingBiz sbiz;

	private static TButtonBiz bbiz;

	private static Org00Biz obiz;

	private static TSessionBiz ssbiz;

	private static TGroupBiz gbiz;

	private static TQuestionBiz qbiz;

	private static TCrmBiz cbiz;

	private static TChannelBiz chbiz;

	private static TLwBiz lbiz;

	public static void init(TSettingBiz sbiz, TButtonBiz bbiz, Org00Biz obiz, TSessionBiz ssbiz, TGroupBiz gbiz, TQuestionBiz qbiz, TCrmBiz cbiz,
			TChannelBiz chbiz, TLwBiz lbiz) {
		QqVisitorHandler.sbiz = sbiz;
		QqVisitorHandler.bbiz = bbiz;
		QqVisitorHandler.obiz = obiz;
		QqVisitorHandler.ssbiz = ssbiz;
		QqVisitorHandler.gbiz = gbiz;
		QqVisitorHandler.qbiz = qbiz;
		QqVisitorHandler.cbiz = cbiz;
		QqVisitorHandler.chbiz = chbiz;
		QqVisitorHandler.lbiz = lbiz;
	}

	private static Logger log = LoggerFactory.getLogger(QqVisitorHandler.class);

	/**
	 * 收到消息
	 * 
	 * @param message
	 * @param user
	 * @param smartQQClient
	 * @return
	 */
	public static boolean chat(Message message, UserInfo user, SmartQQClient smartQQClient) {
		String id = "Q" + System.currentTimeMillis() + CU.getSerial("");
		log.info("坐席收到QQ的消息：from [{}]  to [{}] by id[{}]", message.getUserId(), user.getAccount(), id);
		try {
			VisitorForm cf = new VisitorForm();
			cf.setId(id);
			cf.setCid(String.valueOf(message.getUserId()));
			TChannel channel = chbiz.getChannelByQq(user.getAccount());
			cf.setChannel(channel.getNo());
			cf.setPid(channel.getPid());

			QqClient visitorClient = (QqClient) ClientManager.getInstance().getClient(cf.getCid());
			// 首次发送消息
			if (visitorClient == null || visitorClient.getSessionByPid(cf.getPid()) == null) {
				visitorClient = logon(cf);
				visitorClient.setAgentQQClient(smartQQClient);
				visitorClient.setWechatStep(WECHAT_STEP.INIT);
			} else {// 每次消息都设置active，保活
				visitorClient.setLastActiveGet();
			}

			String content = message.getContent();
			handle(visitorClient, content, cf);
		} catch (MyException e) {
			log.error("", e.getException());
		} catch (Exception e) {
			log.error("", e);
		}
		return true;
	}

	private static boolean handle(QqClient visitorClient, String content, VisitorForm cf) {
		// 处于初始化
		if (content.equals("88")) {// 收到结束会话,并且不处于初始化
			cf.setEvent(MessageConstant.MESSAGE_EVENT.END_SESSION.name());
			visitorClient.setWechatStep(WECHAT_STEP.INIT);
		} else if (visitorClient.getWechatStep().equals(WECHAT_STEP.INIT)) {
			cf.setEvent(MessageConstant.MESSAGE_EVENT.GET_GROUP.name());
			// 当前处于选择技能组的状态，那么就执行进入技能组
		} else if (visitorClient.getWechatStep().equals(WECHAT_STEP.GET_GROUP)) {
			String group = visitorClient.getWechatGroupIndex().get(content);
			if (group == null) {
				error(cf.getPid(), cf.getCid());
				return false;
			} else {
				cf.setValue(group);
				cf.setEvent(MessageConstant.MESSAGE_EVENT.ENTER_GROUP.name());
			}
			// 当前处于技能组的状态，那么久可以进入聊天了
		} else if (visitorClient.getWechatStep().equals(WECHAT_STEP.IN_GROUP)) {
			SessionWrapper session = visitorClient.getSessionByPid(cf.getPid());
			if (content.equals("66") && session.getSession().getStep().equals(AgentConstant.SESSION_STEP.SELF.name())) {// 进入人工
				cf.setEvent(MessageConstant.MESSAGE_EVENT.ENTER_GROUP.name());
			} else {
				cf.setEvent(MessageConstant.MESSAGE_EVENT.CHAT.name());
				cf.setValue(content);
				if (session.getSession().getStep().equals(AgentConstant.SESSION_STEP.QUEUE.name())) {
					session.getSystem().sysSendText(session.getSetting().getVisitorQueueTip());
				}
			}
		}

		log.info("Handle wechat message[{}] use Event[{}]", cf.getId(), cf.getEvent());
		Map<String, AbstractBiz> bizs = new HashMap<String, AbstractBiz>();
		if (SatisfyProcessor.NAME.equals(cf.getEvent())) {
			bizs.put("ssbiz", ssbiz);
			bizs.put("sbiz", sbiz);
		} else if (ButtonProcessor.NAME.equals(cf.getEvent())) {
			bizs.put("bbiz", bbiz);
		} else if (GetGroupListProcessor.NAME.equals(cf.getEvent()) || MessageConstant.MESSAGE_EVENT.ENTER_GROUP.name().equals(cf.getEvent())) {
			bizs.put("gbiz", gbiz);
			bizs.put("chbiz", chbiz);
		} else if (LwProcessor.NAME.equals(cf.getEvent())) {
			/*
			 * try { TLw lw = new TLw(); CopyUtil.copy(req, lw, null, false);
			 * cf.setObject(lw); } catch (MyException e) { }
			 */
			bizs.put("sbiz", ssbiz);
		} else if (LwDetailProcessor.NAME.equals(cf.getEvent())) {
			bizs.put("lbiz", lbiz);
		} else if (cf.getEvent().equals(MessageConstant.MESSAGE_EVENT.GET_GROUP.name())) {
			visitorClient.getWechatGroupIndex().clear();
		}
		ProcessorResult result = VisitorProcessors.createProcessors().process(bizs, visitorClient, cf);
		if (result != null) {
			Object dt = result.getData();
			if (dt == null) {
				dt = "";
			}
			if (StringUtils.isNotBlank(cf.getEvent())) {
				log.info("[{}] <IQ_MESSAGE> handle result : " + cf.getEvent() + "[{}]", visitorClient.getId(), dt);
			}
			if (result.isSuccess()) {
				// 获取技能组列表
				if (cf.getEvent().equals(MessageConstant.MESSAGE_EVENT.GET_GROUP.name())) {
					visitorClient.setWechatStep(WECHAT_STEP.GET_GROUP);

					Map map = (Map) dt;
					StringBuffer sb = new StringBuffer(String.valueOf(map.get("title")));
					List<TGroup> list = (List<TGroup>) map.get("list");
					for (int i = 0; i < list.size(); i++) {
						TGroup g = list.get(i);
						String index = String.valueOf(i + 1);
						visitorClient.getWechatGroupIndex().put(index, g.getId());
						sb.append("\r\n").append(index).append(" ").append(g.getName());
					}
					visitorClient.getSessionByPid(cf.getPid()).getSystem().sysSendText(sb.toString());
				} else if (MessageConstant.MESSAGE_EVENT.ENTER_GROUP.name().equals(cf.getEvent())) {
					visitorClient.setWechatStep(WECHAT_STEP.IN_GROUP);
				}
			} else {
				error(cf.getPid(), cf.getCid());
				return false;
			}
		} else {
			log.error("[{}] <IQ_MESSAGE> send fail for event[{}]", visitorClient.getId(), cf.getEvent());
			error(cf.getPid(), cf.getCid());
			return false;
		}
		return true;
	}

	/**
	 * 登陆
	 * 
	 * @param cf
	 * @return
	 */
	private static QqClient logon(VisitorForm cf) {
		TCrm crm = null;
		String httpSessionId = String.valueOf(System.currentTimeMillis());
		TOrg org = null;
		TSettingEntity setting = null;
		try {
			org = obiz.getByPid(cf.getPid());
			setting = sbiz.getChannelSetting(cf.getPid(), cf.getChannel(), false);
			crm = cbiz.getOrCreateCrm(null, null, cf, org, setting);
		} catch (MyException e) {
			log.error(cf.getTid() + " catch exception while logon.", e.getException());
			return null;
		}

		QqClient visitorClient = null;
		try {
			visitorClient = new QqClient(chbiz, ssbiz, gbiz, qbiz, cf.getChannel(), crm, httpSessionId);
			ClientManager.getInstance().record(visitorClient);
			log.info("[{}] have no client, so create it [{}], sequence[{}]", crm.getId(), visitorClient, visitorClient.getSequence());

			SessionWrapper sessionOfPid = visitorClient.getSessionByPid(cf.getPid());
			if (sessionOfPid == null) {
				sessionOfPid = visitorClient.initSession(cf.getPid(), setting, "wechat", null);
				sessionOfPid.setSetting(setting);
			} else {
				log.info("[{}] have exist session[{}] for pid[{}]", crm.getId(), sessionOfPid.getId(), cf.getPid());
				sessionOfPid.setSetting(setting);
			}
			sessionOfPid.join(visitorClient, null);

			visitorClient.sendSession(sessionOfPid.getSession());
			visitorClient.notifyStatus(cf.getPid(), null);
		} catch (MyException e) {
			log.error("", e.getException());
		} catch (Exception e) {
			log.error("", e);
		}
		return visitorClient;
	}

	private static void error(String pid, String cid) {
		log.error("Create error for cid [{}] in pid[{}]", cid, pid);
		QqClient visitorClient = (QqClient) ClientManager.getInstance().getClient(cid);
		visitorClient.getSessionByPid(pid).getSystem().sysSendText("输入的消息有误，请重新输入");
	}
}
